home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / pctekap1.arc / TURBOIO.ARC / DOS2IO-2.INC < prev    next >
Text File  |  1985-08-17  |  16KB  |  638 lines

  1. (*
  2.                           Dos2io-2.inc
  3.  
  4.  
  5.  
  6.     Dedicated to the public domain.
  7.  
  8.         -- Cole Brecheen
  9.            17 August 1985
  10. *)
  11.  
  12. {$V-,U-,C-,R-} 
  13. CONST
  14.   SegSize = 6.5536E+4;
  15.  
  16. TYPE
  17.   BitRange = 0..15;
  18.   BitSet = SET OF BitRange;
  19.  
  20.  
  21. PROCEDURE IntegerToBitSet( TheInteger : INTEGER;
  22.                    VAR TheSet : BitSet );
  23. VAR
  24.   tmp: RECORD
  25.      CASE BOOLEAN of
  26.        true: ( IntForm : INTEGER );
  27.        false:( SetForm : BitSet );
  28.        END;
  29. BEGIN {IntegerToBitSet}
  30.   tmp.IntForm := TheInteger;
  31.   TheSet := tmp.SetForm;
  32. END;  {IntegerToBitSet}
  33.  
  34.  
  35. PROCEDURE BitSetToInteger( TheSet : BitSet;
  36.                    VAR TheInteger : INTEGER );
  37. VAR
  38.   tmp: RECORD
  39.      CASE BOOLEAN of
  40.        true: ( IntForm : INTEGER );
  41.        false:( SetForm : BitSet );
  42.        END;
  43. BEGIN {BitSetToInteger}
  44.   tmp.SetForm := TheSet;
  45.   TheInteger := tmp.IntForm;
  46. END;  {BitSetToInteger}
  47.  
  48.  
  49.  
  50. FUNCTION WordToReal( TheWord : INTEGER ): REAL;
  51. var
  52.   storage: real;
  53. BEGIN  {WordToReal}
  54.   IF (TheWord > maxint) OR (TheWord < 0) THEN
  55.     BEGIN
  56.       storage := ord(TheWord);
  57.       WordToReal := storage + maxint + maxint + 2;
  58.     END
  59.   ELSE WordToReal := ORD( TheWord );
  60. END;  {WordToReal}
  61.  
  62.  
  63. FUNCTION RealToWord( TheReal : REAL ): INTEGER;
  64. BEGIN  {RealToWord}
  65.   IF (TheReal < 0) or (TheReal >= segsize)
  66.     THEN abort('Real out of word range:  '+RealStr(TheReal,0,0));
  67.   if TheReal >= (segsize - 1) then
  68.     RealToWord := -1
  69.   else
  70.     IF TheReal > maxint THEN
  71.       RealToWord := maxint + round(TheReal - maxint)
  72.     ELSE RealToWord := round(TheReal);
  73. END;  {RealToWord}
  74.  
  75.  
  76.  
  77.  
  78. PROCEDURE RealToSegmented( TheReal: REAL;
  79.                    VAR TheSeg, TheOfs: INTEGER );
  80. BEGIN {RealToSegmented}
  81.   IF TheReal > SegSize THEN
  82.     TheSeg := trunc(TheReal / SegSize)
  83.   ELSE
  84.     TheSeg := 0;
  85.   TheOfs := RealToWord( TheReal - (TheSeg * SegSize) );
  86. END; {RealToSegmented}
  87.  
  88.  
  89. FUNCTION SegmentedToReal( TheSeg, TheOfs: INTEGER ): REAL;
  90. VAR
  91.   tmp: REAL;
  92. BEGIN {SegmentedToReal}
  93.   tmp := WordToReal( TheSeg ) * SegSize;
  94.   SegmentedToReal := WordToReal( TheOfs ) + tmp;
  95. END; {SegmentedToReal}
  96.  
  97.  
  98.  
  99.  
  100. PROCEDURE lowerch( VAR TheCh : CHAR );
  101.     {Converts TheCh to lower case.}
  102. BEGIN
  103.   IF TheCh in ['A'..'Z']
  104.     THEN TheCh := chr( ord(TheCh) + 32 );
  105. END; {lowerch}
  106.  
  107.  
  108.  
  109. FUNCTION  BlockRead ( FileHandle : INTEGER;
  110.                VAR buffer : buftype;
  111.                BlockNumber : INTEGER ): ErrorMessage;
  112. VAR
  113.   rgstr : RegPack;
  114.   BlksInSeg : integer;
  115. BEGIN {BlockRead}
  116.   BlockRead := NoError;
  117.   BlksInSeg := trunc( SegSize / BufSize );
  118.   WITH rgstr DO BEGIN
  119.     a.h := $42;  {command to move file read/write pointer}
  120.     a.l := 0;
  121.     {moves pointer to offset bytes from beginnning of file}
  122.     b.x := FileHandle;
  123.     c.x := BlockNumber DIV BlksInSeg;
  124.     d.x := (BlockNumber - (c.x * BlksInSeg)) * BufSize;
  125.     msdos( rgstr );
  126.     IF FlaggedError( flags )
  127.       THEN BEGIN {writeln('Blockread error');  } {diag}
  128.           PrintMessage( MessageType( a.x ) );
  129.           END;
  130.  
  131.     b.x := FileHandle;
  132.     c.x := BufSize;
  133.     a.h := $3F;  {Read from a file or device.}
  134.     d.x := ofs( buffer );
  135.     ds := seg( buffer );
  136.     msdos( rgstr );
  137.     IF FlaggedError( flags )
  138.       THEN BlockRead := MessageType( a.x )
  139.       ELSE
  140.     BEGIN
  141.       IF a.x < c.x
  142.         THEN
  143.           IF a.x = 0
  144.         THEN BlockRead := EndOfFile
  145.         ELSE BlockRead := PartialRead
  146.         ELSE BlockRead := NoError;
  147.     END
  148.   END; {WITH rgstr}
  149. END;  {BlockRead}
  150.  
  151.  
  152.  
  153. FUNCTION BlockWrite( FileHandle : INTEGER;
  154.              VAR buffer : buftype;
  155.              BlockNumber : INTEGER ): ErrorMessage;
  156. VAR
  157.   rgstr : RegPack;
  158.   BlksInSeg : integer;
  159. BEGIN {BlockWrite}
  160.   BlockWrite := NoError;
  161.   BlksInSeg := trunc( SegSize / BufSize );
  162.   WITH rgstr DO BEGIN
  163.     a.h := $42;  {command to move file read/write pointer}
  164.     a.l := 0;
  165.     {moves pointer to offset bytes from beginnning of file}
  166.     b.x := FileHandle;
  167.     c.x := BlockNumber DIV BlksInSeg;
  168.     d.x := (BlockNumber - (c.x * BlksInSeg))* BufSize;
  169.     msdos( rgstr );
  170.     IF FlaggedError( flags )
  171.       THEN PrintMessage( MessageType( a.x ) );
  172.  
  173.     b.x := FileHandle;
  174.     c.x := BufSize;
  175.     a.h := $40; {Write to a file or device.}
  176.     d.x := ofs( buffer );
  177.     ds := seg( buffer );
  178.     msdos( rgstr );
  179.     IF a.x < c.x  {if fewer than c.x bytes were actually written}
  180.       THEN abort( 'No room to write.' );
  181.     IF FlaggedError( flags )
  182.       THEN BlockWrite := MessageType( a.x );
  183.   END; {WITH rgstr}
  184. END; {BlockWrite}  
  185.  
  186.  
  187.  
  188. PROCEDURE GetProgramParameter( VAR ParamStr : dos2str80 );
  189. VAR
  190.   TmpStr : string[80] absolute cseg:$0080;
  191. BEGIN {GetProgramParameter}
  192.   IF length( TmpStr ) > 1 THEN
  193.     ParamStr := copy( TmpStr, 2, length(TmpStr) - 1 )
  194.     {We start at 2 and copy length - 1 because the first
  195.     character in the parameter will always be a space.}
  196.   ELSE
  197.     ParamStr := null;
  198. END;  {GetProgramParameter}
  199.  
  200.  
  201.  
  202.  
  203. FUNCTION CloseHandle ( FileHandle : INTEGER ): ErrorMessage;
  204. LABEL EndProcedure;
  205. VAR
  206.   TmpPtr : BufferPtr;
  207.   rgstr : RegPack;
  208. BEGIN {CloseHandle}
  209.   CloseHandle := NoError;
  210.   WITH rgstr DO BEGIN
  211.     a.h := $3E;  {close a FileHandle}
  212.     b.x := FileHandle;
  213.     msdos( rgstr );
  214.     IF FlaggedError( flags )
  215.       THEN CloseHandle := MessageType( a.x );
  216.   END; {WITH rgstr}
  217.  
  218.   CheckInitialization;
  219.     {From here down we are releasing any memory that ReadStr
  220.     may have allocated to FileHandle for buffering purposes.}
  221.  
  222.   IF BufLstBase = nil
  223.     THEN GOTO EndProcedure;
  224.   TmpPtr := BufLstBase;
  225.   IF (TmpPtr^.next = NIL) AND (TmpPtr^.handle = FileHandle) THEN 
  226.     BufLstBase := NIL                         {added 6/6/85}
  227.   ELSE  WHILE (TmpPtr^.next <> nil)
  228.     and
  229.     (TmpPtr^.handle <> FileHandle) DO TmpPtr := TmpPtr^.next;
  230.   IF TmpPtr^.handle = FileHandle
  231.     THEN
  232.       BEGIN
  233.     IF TmpPtr^.prev <> NIL THEN TmpPtr^.prev^.next := TmpPtr^.next;
  234.     IF TmpPtr^.next <> NIL THEN TmpPtr^.next^.prev := TmpPtr^.prev;
  235.     dispose( TmpPtr );
  236.       END;
  237.   EndProcedure:
  238. END;  {CloseHandle}
  239.  
  240.  
  241.  
  242. FUNCTION FileLength( FileHandle : INTEGER ): REAL;
  243.     {Returns the number of bytes in the file identified by
  244.     FileHandle.}
  245. VAR
  246.   rgstr : RegPack;
  247.   tmp : REAL;
  248.   OldSeg, OldOfs : INTEGER;
  249. BEGIN {FileLength}
  250.   WITH rgstr DO BEGIN
  251.     a.l := 1;  {move pointer to current location plus offset}
  252.     a.h := $42;
  253.     b.x := FileHandle;
  254.     c.x := 0;  {most significant part of the offset}
  255.     d.x := 0;  {least significant part of the offset}
  256.     msdos( rgstr );
  257.     IF FlaggedError( flags )
  258.       THEN BEGIN { writeln('filelength error'); } {diag}
  259.         PrintMessage( MessageType( a.x ) );
  260.       END;
  261.     OldSeg := d.x;
  262.     OldOfs := a.x;
  263.     {We save these values so we can restore the pointer to
  264.     its original location.}
  265.  
  266.     a.l := 2;  {move pointer to end of file plus offset}
  267.     a.h := $42;
  268.     b.x := FileHandle;
  269.     c.x := 0;  {most significant part of the offset}
  270.     d.x := 0;  {least significant part of the offset}
  271.     msdos( rgstr );
  272.     IF FlaggedError( flags )
  273.       THEN BEGIN { writeln('filelength error'); } {diag}
  274.         PrintMessage( MessageType( a.x ) );
  275.       END;
  276.     FileLength := SegmentedToReal( d.x, a.x );
  277.  
  278.     a.l := 0;
  279.     {move pointer to offset bytes from beginning of file}
  280.     a.h := $42;
  281.     b.x := FileHandle;
  282.     c.x := OldSeg;  {most significant part of the offset}
  283.     d.x := OldOfs;  {least significant part of the offset}
  284.     msdos( rgstr );
  285.       {Restores pointer to its original location.}
  286.     IF FlaggedError( flags )
  287.       THEN BEGIN { writeln('filelength error'); } {diag}
  288.         PrintMessage( MessageType( a.x ) );
  289.       END;
  290.   END; {WITH rgstr}
  291. END; {FileLength}
  292.  
  293.  
  294.  
  295. FUNCTION  OpenFile ( VAR FileHandle : INTEGER;
  296.                 fname : dos2str80): ErrorMessage;
  297. VAR
  298.   rgstr : RegPack;
  299. BEGIN  {OpenFile}
  300.   FileHandle := 0;
  301.   OpenFile := NoError;
  302.   MakeAsciiZ( fname );
  303.   WITH rgstr DO BEGIN
  304.     a.h := $3D;   {open a file}
  305.     A.L := 2;     {for reading and writing}
  306.     b.x := 0;
  307.     c.x := 0;
  308.     d.x := ofs( fname );
  309.     ds := seg( fname );
  310.     msdos( rgstr );
  311.     IF FlaggedError( flags )
  312.       THEN OpenFile := MessageType( a.x )
  313.       ELSE FileHandle := a.x;
  314.   END; {WITH rgstr}
  315. END;  {OpenFile}
  316.  
  317.  
  318.  
  319. FUNCTION  CreateFile ( VAR FileHandle : INTEGER;
  320.              fname : dos2str80): ErrorMessage;
  321. VAR
  322.   rgstr : RegPack;
  323. BEGIN  {CreateFile}
  324.   FileHandle := 0;
  325.   CreateFile := NoError;
  326.   MakeAsciiZ( fname );
  327.  
  328.   WITH rgstr DO BEGIN
  329.     a.h := $3C;   {create a file}
  330.     A.L := 0;
  331.     b.x := 0;
  332.     c.x := 0;  {attribute of the file; 0 makes it normal}
  333.     d.x := ofs( fname );
  334.     ds := seg( fname );
  335.     msdos( rgstr );
  336.     IF FlaggedError( flags )
  337.       THEN CreateFile := MessageType( a.x )
  338.       ELSE FileHandle := a.x;
  339.   END; {WITH rgstr}
  340. END;  {CreateFile}
  341.  
  342.  
  343.  
  344. FUNCTION EndFile( FileHandle : INTEGER ): BOOLEAN;
  345. VAR
  346.   rgstr : RegPack;
  347.   OldSeg, OldOfs : INTEGER;
  348. BEGIN {EndFile}
  349.   WITH rgstr DO BEGIN
  350.     a.l := 1;  {move pointer to current location plus offset}
  351.     a.h := $42;
  352.     b.x := FileHandle;
  353.     c.x := 0;  {most significant part of the offset}
  354.     d.x := 0;  {least significant part of the offset}
  355.     msdos( rgstr );
  356.     OldSeg := d.x;
  357.     OldOfs := a.x;
  358.  
  359.     a.l := 2;  {move pointer to end of file plus offset}
  360.     a.h := $42;
  361.     b.x := FileHandle;
  362.     c.x := 0;  {most significant part of the offset}
  363.     d.x := 0;  {least significant part of the offset}
  364.     msdos( rgstr );
  365.     EndFile := (d.x <= OldSeg) and (a.x <= OldOfs);
  366.  
  367.     a.l := 0;
  368.     {move pointer to offset bytes from beginning of file}
  369.     a.h := $42;
  370.     b.x := FileHandle;
  371.     c.x := OldSeg;  {most significant part of the offset}
  372.     d.x := OldOfs;  {least significant part of the offset}
  373.     msdos( rgstr );
  374.       {Restores pointer to its original location.}
  375.   END; {WITH rgstr}
  376. END; {EndFile}  
  377.  
  378.  
  379.  
  380. FUNCTION RenameFile( OldFileName,
  381.              NewFileName :  Dos2str80 ): ErrorMessage;
  382. VAR
  383.   rgstr : RegPack;
  384. BEGIN {RenameFile}
  385.   RenameFile := NoError;
  386.   IF pos( ':', NewFileName ) = 2
  387.     THEN delete( NewFileName, 1, 2 );
  388.   IF pos( ':', OldFileName ) = 2
  389.     THEN insert( copy(OldFileName, 1, 2), NewFileName, 1 );
  390.   MakeAsciiZ( OldFileName );
  391.   MakeAsciiZ( NewFileName );
  392.   WITH rgstr DO BEGIN
  393.     ds := seg( OldFileName );
  394.     d.x := ofs( OldFileName );
  395.     es := seg( NewFileName );
  396.     di := ofs( NewFileName );
  397.     a.h := $56; {Rename a file.}
  398.     msdos( rgstr );
  399.     IF FlaggedError( flags )
  400.       THEN RenameFile := MessageType( a.x );
  401.   END; {WITH rgstr}
  402. END; {RenameFile}
  403.  
  404.  
  405.  
  406. FUNCTION DeleteFile( FileName : Dos2str80 ): ErrorMessage;
  407. VAR
  408.   rgstr : RegPack;
  409. BEGIN {DeleteFile}
  410.   DeleteFile := NoError;
  411.   MakeAsciiZ( FileName );
  412.   WITH rgstr DO BEGIN
  413.     ds := seg( FileName );
  414.     d.x := ofs( FileName );
  415.     a.h := $41; {Delete a file from a specified directory.}
  416.     msdos( rgstr );
  417.     IF FlaggedError( flags )
  418.       THEN DeleteFile := MessageType ( a.x );
  419.   END; {WITH rgstr}
  420. END; {DeleteFile}
  421.  
  422.  
  423. TYPE
  424.   FileMode = (NormalFile, ReadOnlyFile, HiddenFile, SystemFile);
  425.   ModeSet = set of FileMode;
  426.  
  427. FUNCTION SetFileMode( FileName: dos2str80;
  428.               TheSet: ModeSet ): ErrorMessage;
  429. VAR
  430.   TmpMode : FileMode;
  431.   rgstr : RegPack;
  432.   TmpSet : BitSet;
  433. BEGIN {SetFileMode}
  434.   SetFileMode := NoError;
  435.   MakeAsciiZ( FileName );
  436.   WITH rgstr DO BEGIN
  437.     a.h := $43; {Change file mode command (CHMOD).}
  438.     a.l := 1;
  439.     {Indicates that we want to change the mode rather than
  440.     find out what it presently is.}
  441.     ds := seg( FileName );
  442.     d.x := ofs( FileName );
  443.  
  444.     TmpSet := [];
  445.     TmpMode := NormalFile;
  446.     WHILE TheSet <> [] DO BEGIN
  447.       IF TmpMode in TheSet THEN
  448.     CASE TmpMode of
  449.       NormalFile:
  450.         BEGIN
  451.           TmpSet := [];
  452.           TheSet := [];
  453.         END;
  454.       ReadOnlyFile: TmpSet := TmpSet + [0];
  455.       HiddenFile: TmpSet := TmpSet + [1];
  456.       SystemFile: TmpSet := TmpSet + [2];
  457.     END; {case}
  458.       IF TheSet <> [] THEN
  459.     TheSet := TheSet - [TmpMode];
  460.       TmpMode := succ( TmpMode );
  461.     END; {while}
  462.  
  463.     BitSetToInteger( TmpSet, c.x );
  464.     msdos( rgstr );
  465.     IF FlaggedError( flags ) THEN
  466.       SetFileMode := MessageType( a.x );
  467.   END; {WITH rgstr}
  468. END; {SetFileMode}    
  469.  
  470.  
  471. FUNCTION GetFileMode( FileName: dos2str80;
  472.               VAR TheSet: ModeSet ): ErrorMessage;
  473. VAR
  474.   rgstr : RegPack;
  475.   TmpSet : BitSet;
  476. BEGIN {GetFileMode}
  477.   MakeAsciiZ( FileName );
  478.   GetFileMode := NoError;
  479.   TheSet := [];
  480.   WITH rgstr DO BEGIN
  481.     a.h := $43; {Change file mode command (CHMOD).}
  482.     a.l := 0; {Indicates that we want the file's present mode.}
  483.     ds := seg( FileName );
  484.     d.x := ofs( FileName );
  485.     msdos( rgstr );
  486.     IF FlaggedError( flags ) THEN
  487.       GetFileMode := MessageType( a.x )
  488.     ELSE
  489.       BEGIN
  490.     IntegerToBitSet( c.x, TmpSet );
  491.     TheSet := [NormalFile];
  492.     IF 2 in TmpSet THEN
  493.       TheSet := TheSet + [SystemFile];
  494.     IF 1 in TmpSet THEN
  495.       TheSet := TheSet + [HiddenFile];
  496.     IF 0 in TmpSet THEN
  497.       TheSet := TheSet + [ReadOnlyFile];
  498.     IF TheSet <> [NormalFile] THEN
  499.     {i.e., if something's been added}
  500.       TheSet := TheSet - [NormalFile];
  501.       END;
  502.   END; {WITH rgstr}
  503. END; {GetFileMode}
  504.  
  505.  
  506.  
  507. FUNCTION DefaultDrive: CHAR;
  508.     {Returns the current default drive as a lower case
  509.     letter.}
  510. VAR
  511.   rgstr : RegPack;
  512. BEGIN  {DefaultDrive}
  513.   rgstr.a.h := $19;  {DOS "current disk" function number}
  514.   msdos( rgstr );
  515.   DefaultDrive := CHR( ORD(rgstr.a.l) + ORD( 'a' ) );
  516. END;  {DefaultDrive}
  517.  
  518.  
  519.  
  520. PROCEDURE SetDefaultDrive( DriveLetter: CHAR );
  521. VAR
  522.   rgstr : RegPack;
  523. BEGIN {SetDefaultDrive}
  524.   lowerch( DriveLetter );
  525.   IF not (DriveLetter in ['a'..'z'])
  526.     THEN PrintMessage( InvalidDrive );
  527.   rgstr.a.h := $E;
  528.   rgstr.d.l := ord( DriveLetter ) - ord( 'a' );
  529.   msdos( rgstr );
  530. END; {SetDefaultDrive}
  531.  
  532.  
  533.  
  534. PROCEDURE GetDate( VAR month, day, year: INTEGER );
  535. VAR
  536.   rgstr : RegPack;
  537. BEGIN {GetDate}
  538.   WITH rgstr DO BEGIN
  539.     a.h := $2A;  {DOS "get date" function number}
  540.     msdos( rgstr );
  541.     month := d.h;
  542.     day := d.l;
  543.     year := c.x;
  544.   END; {WITH rgstr}
  545. END;  {GetDate}
  546.  
  547.  
  548.  
  549. PROCEDURE SetDate( month, day, year: INTEGER );
  550. VAR
  551.   rgstr : RegPack;
  552.  
  553.   PROCEDURE quit;
  554.   BEGIN
  555.     abort('Invalid date.');
  556.   END;
  557.  
  558. BEGIN {SetDate}
  559.   WITH rgstr DO
  560.     BEGIN
  561.       a.h := $2B; {Set date function number}
  562.       IF year < 1900
  563.     THEN year := year + 1900;
  564.       IF (year >= 1980) and (year <= 2099)
  565.     THEN c.x := year
  566.     ELSE quit;
  567.       IF month in [1..12]
  568.     THEN d.h := month
  569.     ELSE quit;
  570.       IF day in [1..31]
  571.     THEN d.l := day
  572.     ELSE quit;
  573.       msdos( rgstr );
  574.     END; {WITH rgstr}
  575. END; {SetDate}
  576.  
  577.  
  578.  
  579. FUNCTION MkDir( DirName: dos2str80 ): ErrorMessage;
  580. VAR
  581.   rgstr : RegPack;
  582. BEGIN {MkDir}
  583.   MkDir := NoError;
  584.   MakeAsciiZ( DirName );
  585.   WITH rgstr DO BEGIN
  586.     a.h := $39; {Create a sub-directory.}
  587.     ds := seg( DirName );
  588.     d.x := ofs( DirName );
  589.     msdos( rgstr );
  590.     IF FlaggedError( flags )
  591.       THEN MkDir := MessageType( a.x );
  592.   END; {WITH rgstr}
  593. END; {MkDir}
  594.  
  595.  
  596. FUNCTION RmDir( DirName: dos2str80 ): ErrorMessage;
  597. VAR
  598.   rgstr : RegPack;
  599. BEGIN {RmDir}
  600.   RmDir := NoError;
  601.   MakeAsciiZ( DirName );
  602.   WITH rgstr DO BEGIN
  603.     a.h := $3A; {Remove a directory entry}
  604.     ds := seg( DirName );
  605.     d.x := ofs( DirName );
  606.     msdos( rgstr );
  607.     IF FlaggedError( flags )
  608.       THEN RmDir := MessageType( a.x );
  609.   END; {WITH rgstr}
  610. END; {RmDir}
  611.  
  612.  
  613. FUNCTION ChDir( DirName: dos2str80 ): ErrorMessage;
  614. VAR
  615.   rgstr : RegPack;
  616. BEGIN {ChDir}
  617.   ChDir := NoError;
  618.   MakeAsciiZ( DirName );
  619.   WITH rgstr DO BEGIN
  620.     a.h := $3B; {Change the current directory}
  621.     ds := seg( DirName );
  622.     d.x := ofs( DirName );
  623.     msdos( rgstr );
  624.     IF FlaggedError( flags )
  625.       THEN ChDir := MessageType( a.x );
  626.   END; {WITH rgstr}
  627. END; {ChDir}
  628.  
  629. FUNCTION FileExists( fname: dos2str80 ): BOOLEAN;
  630. VAR dumset: ModeSet;
  631.     resultofgfm: ErrorMessage;
  632. BEGIN {FileExists}
  633.   resultofgfm := GetFileMode( fname, dumset);
  634.   IF resultofgfm IN [FileNotFound, PathNotFound] THEN
  635.     FileExists := FALSE
  636.   ELSE FileExists := TRUE;
  637. END; {FileExists}
  638.